package com.gzxx.exception;

import com.gzxx.constant.ServiceCodeStatus;
import com.gzxx.util.ServerResponse;
import io.jsonwebtoken.MalformedJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * @author MAX
 * @date 2020/7/23 10:27 上午
 * 全局异常处理
 */

@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ServerResponse handleException(Exception e) {
        log.error("服务器异常", e);
        return ServerResponse.error();
    }

    @ExceptionHandler(ServiceException.class)
    public ServerResponse handleServiceException(ServiceException e) {
        return ServerResponse.error(e.getMessage());
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public ServerResponse handleNoFoundException(Exception e) {
        log.error("请求404异常", e);
        return ServerResponse.error(ServiceCodeStatus.FAILURE, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public ServerResponse handleDuplicateKeyException(DuplicateKeyException e) {
        log.error("重复键异常", e);
        return ServerResponse.error("数据库中已存在该记录");
    }

    @ExceptionHandler(AccountExpiredException.class)
    public ServerResponse handleAccountExpiredException(AccountExpiredException e) {
        log.error(e.getMessage(), e);
        return ServerResponse.error(ServiceCodeStatus.ACCOUNT_EXPIRED, e.getMessage());
    }

    @ExceptionHandler(MalformedJwtException.class)
    public ServerResponse handleMalformedJwtException(MalformedJwtException e) {
        log.error(e.getMessage(), e);
        return ServerResponse.error(ServiceCodeStatus.TOKEN_INVALID, e.getMessage());
    }

    @ExceptionHandler(AccessDeniedException.class)
    public ServerResponse handleDuplicateKeyException(AccessDeniedException e) {
        log.error(e.getMessage(), e);
        return ServerResponse.error(ServiceCodeStatus.FAILURE, "暂无权限操作，请联系管理员");
    }

    @ExceptionHandler({BindException.class})
    public ServerResponse handleBindException(BindException e) {
        String msg = "参数错误，请确认";
        BindingResult bindingResult = e.getBindingResult();
        if (bindingResult.hasErrors()) {
            ObjectError error = bindingResult.getAllErrors().get(0);
            msg = error.getDefaultMessage();
        }
        return ServerResponse.error(msg);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ServerResponse handleArgumentNotValidException(MethodArgumentNotValidException e) {
        String msg = "参数错误，请确认";
        BindingResult bindingResult = e.getBindingResult();
        if (bindingResult.hasErrors()) {
            ObjectError error = bindingResult.getAllErrors().get(0);
            msg = error.getDefaultMessage();
        }
        return ServerResponse.error(msg);
    }
}
